package com.yy.QSManage.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.yy.QSManage.dao.FaSysFileMapper;
import com.yy.QSManage.enums.FileExtEnum;
import com.yy.QSManage.exception.ServiceException;
import com.yy.QSManage.model.entity.FaSysFile;
import com.yy.QSManage.service.FaSysFileService;
import com.yy.QSManage.service.base.impl.BaseServiceImpl;
import com.yy.QSManage.tool.FileUniqueIdentifier;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Objects;


@Service
public class FaSysFileServiceImpl extends BaseServiceImpl<FaSysFileMapper, FaSysFile> implements FaSysFileService {

    @Value("${file.upload_origin}")
    private String uploadOrigin;

    @Value("${file.upload-dir}") // 自动注入配置路径
    private String uploadDir;

    @Override
    public FaSysFile upload(MultipartFile file) {
        return upload(file, file.getOriginalFilename());
    }

    @Override
    public FaSysFile upload(MultipartFile file, String newFileName) {
        if (null == file) {
            throw  new ServiceException("文件缺失！");
        }
        // 判断文件后缀是否合法
        String originalFilename = file.getOriginalFilename();
        String ext = FileUtil.extName(originalFilename);
        FileExtEnum uploadExclude = FileExtEnum.UploadExclude;
        if(Arrays.asList(uploadExclude.getExts()).contains(ext)){
            throw new ServiceException(uploadExclude.getExplain());
        }
        // 创建临时文件
        File tempFile = FileUtil.createTempFile(".temp",true);
        try {
            FileUtil.writeFromStream(file.getInputStream(), tempFile, true);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return upload(tempFile, newFileName);
    }

    @Override
    public FaSysFile upload(File file, String newFileName) {
        // 转换文件名异常字符
        newFileName = newFileName.replaceAll("(?:&|#)","_");
        // 获取文件后缀
        String originalFilename = newFileName.split("\\.")[1];
        // 获取上传文件code
        String code = FileUniqueIdentifier.generateFileMD5(file);
        // 判断文件是否存在
        FaSysFile sysFile = getByParam(FaSysFile::getCode, code);
        if(Objects.isNull(sysFile)){
            // 判断文件名是否重复
            if(ifExist(FaSysFile::getName, newFileName)){
                // 获取当前时间戳为文件名
                newFileName = String.valueOf(DateUtil.currentSeconds()).concat(".").concat(originalFilename);
            }
            // 将文件保存到本地
            Path path = Paths.get(uploadDir, newFileName);
            try {
                Files.createDirectories(path.getParent());// 自动创建目录
            }catch (Exception e){
                log.error(e.getMessage());
                throw new ServiceException(e.getMessage());
            }
            File targetFile = new File(uploadDir + File.separator + newFileName);
            try {
                // 复制文件（使用Apache Commons IO）
                FileUtils.copyFile(file, targetFile);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            // 保存文件信息到数据库
            FaSysFile faSysFile = new FaSysFile();
            String[] split = newFileName.split("\\.");
            String type = split[split.length-1];
            // 拼接网络访问路径
            String urlPath = uploadOrigin.concat(uploadDir +newFileName);
            faSysFile.setName(newFileName)
                    .setType(type)
                    .setCode(code)
                    .setPath(path.toString())
                    .setUrl(urlPath);
            save(faSysFile);
            sysFile = getByParam(FaSysFile::getCode, code);
        }
        file.delete();
        return sysFile;
    }
}
